﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using VNTG.UserProfileFilters;

namespace VNTG.UserProfileFilters.Examples
{
    /// <summary>
    /// Program to show some examples on how to create user profile exclusion filters using
    /// code (and some reflection).
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            // Execute example 1
            CreateFilterExample1();

            // Uncomment to execute example 2 (don't forget to comment ex1 then!)
            //CreateFilterExample2();
        }

        /// <summary>
        /// This example creates a user profile exclusion filter on the "Local AD" 
        /// connection using the internal DSML objects.
        /// 
        /// User rules (any apply / or):
        /// - userAccountControl bit on equals 2
        /// - company equals "ventigrate"
        /// 
        /// Group rules:
        /// - name equals "test"
        /// </summary>
        public static void CreateFilterExample1()
        {
            // Get a reference to the first available user profile service app
            SPFarm localFarm = SPFarm.Local;
            var upServiceproxy = SPFarm.Local.Services.Where(s => s.GetType().Name.Contains("UserProfileService")).FirstOrDefault();

            if (upServiceproxy != null)
            {
                var upServiceApp = upServiceproxy.Applications.OfType<SPIisWebServiceApplication>().FirstOrDefault();
                if (upServiceApp == null)
                {
                    Console.WriteLine("No User profile svc app found");
                    return;
                }

                SPServiceContext ctx = SPServiceContext.GetContext(upServiceApp.ServiceApplicationProxyGroup, SPSiteSubscriptionIdentifier.Default);
                Microsoft.Office.Server.UserProfiles.UserProfileConfigManager upConfigManager = new Microsoft.Office.Server.UserProfiles.UserProfileConfigManager(ctx);

                // Let's create some user filters for the sync connection called "Local AD"
                var connection = upConfigManager.ConnectionManager["Local AD"];                
                if (connection != null)
                {
                    //----------------------------------------------
                    // Create a set of user-related rules, any apply
                    //----------------------------------------------
                    Filters userFilter = new Filters("user");
                    var fsCondition1 = userFilter.CreateFilterSetCondition(connection, "userAccountControl", Filters.FilterOperator.Bit_on, "2");
                    var fsCondition2 = userFilter.CreateFilterSetCondition(connection, "company", Filters.FilterOperator.Equals, "ventigrate");

                    // get the actual filterset based on an OR between all conditions
                    List<object> conditions = new List<object>();
                    conditions.Add(fsCondition1);
                    conditions.Add(fsCondition2);
                    var userFilterSet = userFilter.GenerateFilterSetForConditions(conditions, Filters.FilterSetOperator.Or);

                    //------------------------------------------------------
                    // Create a set of group-related rules, all apply (=AND)
                    //------------------------------------------------------
                    Filters groupFilter = new Filters("group");
                    var groupCondition1 = groupFilter.CreateFilterSetCondition(connection, "name", Filters.FilterOperator.Equals, "test");

                    conditions = new List<object>();
                    conditions.Add(groupCondition1);
                    var groupFilterSet = groupFilter.GenerateFilterSetForConditions(conditions, Filters.FilterSetOperator.And);

                    //---------------------------------------------
                    // Add the created filtersets to the connection
                    //---------------------------------------------
                    Filters helper = new Filters(string.Empty);
                    helper.SetExclusionFilters(connection, userFilterSet, groupFilterSet);
                }
            }
        }

        /// <summary>
        /// Example 2: create a exclusion filter on the first available connection, based on user-only rules.
        /// In this case, the DSML-related properties (IsNumeric) are provided manually in the 
        /// CreateFilterSetCondition method. This will be a bit faster than example 1, in which IsNumeric 
        /// property was fetched dynamically using reflection.        
        /// </summary>
        public static void CreateFilterExample2()
        {
            // Get a reference to the first available user profile service app
            SPFarm localFarm = SPFarm.Local;
            var upServiceproxy = SPFarm.Local.Services.Where(s => s.GetType().Name.Contains("UserProfileService")).FirstOrDefault();

            if (upServiceproxy != null)
            {
                var upServiceApp = upServiceproxy.Applications.OfType<SPIisWebServiceApplication>().FirstOrDefault();
                if (upServiceApp == null)
                {
                    Console.WriteLine("No User profile svc app found");
                    return;
                }

                SPServiceContext ctx = SPServiceContext.GetContext(upServiceApp.ServiceApplicationProxyGroup, SPSiteSubscriptionIdentifier.Default);
                Microsoft.Office.Server.UserProfiles.UserProfileConfigManager upConfigManager = new Microsoft.Office.Server.UserProfiles.UserProfileConfigManager(ctx);

                // Let's create some user filters for the first available sync connection
                var connection = upConfigManager.ConnectionManager.FirstOrDefault();
                if (connection != null)
                {
                    //----------------------------------------------
                    // Create a set of user-related rules, all apply
                    //----------------------------------------------
                    Filters userFilter = new Filters("user");
                    var fsCondition1 = userFilter.CreateFilterSetCondition("userAccountControl", Filters.FilterOperator.Bit_on, "2", true);
                    var fsCondition2 = userFilter.CreateFilterSetCondition("company", Filters.FilterOperator.Equals, "ventigrate", false);     

                    // get the actual filterset based on an AND between all conditions
                    List<object> conditions = new List<object>();
                    conditions.Add(fsCondition1);
                    conditions.Add(fsCondition2);                    
                    var userFilterSet = userFilter.GenerateFilterSetForConditions(conditions, Filters.FilterSetOperator.Or);
                                        
                    //---------------------------------------------
                    // Add the created filtersets to the connection
                    //---------------------------------------------
                    Filters helper = new Filters("");
                    helper.SetExclusionFilters(connection, userFilterSet);
                }
            }
        }
    }
}
